﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Models;

namespace AIStudio.Wpf.DiagramDesigner
{
    public class FullyCreatedConnectorInfo : ConnectorInfoBase
    {
        public FullyCreatedConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false)
           : this(null, dataItem, orientation, isInnerPoint, isPortless)
        {
        }

        public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false)
            : base(root, orientation)
        {
            this.Parent = dataItem;
            this.IsInnerPoint = isInnerPoint;
            this.IsPortless = IsPortless;

            if (IsInnerPoint == true)
            {
                BuildMenuOptions();
            }
        }

        public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SelectableItemBase designer) : base(root, designer)
        {
            this.Parent = dataItem;
            if (IsInnerPoint == true)
            {
                BuildMenuOptions();
            }
        }

        public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
        {
            this.Parent = dataItem;
            if (IsInnerPoint == true)
            {
                BuildMenuOptions();
            }
        }

        public override SelectableItemBase GetSerializableObject()
        {
            return new FullyCreatedConnectorInfoItem(this);
        }

        protected override void Init(IDiagramViewModel root, bool initNew)
        {
            base.Init(root, initNew);

            menuOptions = new List<CinchMenuItem>();
            MenuItemCommand = new SimpleCommand(Command_Enable, ExecuteMenuItemCommand);
            DeleteCommand = new SimpleCommand(Command_Enable, ExecuteDeleteCommand);
        
        }

        protected override void InitNew()
        {
            base.InitNew();
        }

        protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
        {
            base.LoadDesignerItemViewModel(designerbase);

            if (designerbase is FullyCreatedConnectorInfoItem designer)
            {
                XRatio = designer.XRatio;
                YRatio = designer.YRatio;
                IsInnerPoint = designer.IsInnerPoint;
                IsPortless = designer.IsPortless;
            }
        }

        #region 属性
        public override PointBase Position
        {
            get
            {
                return PointHelper.GetPointForConnector(this);
            }
        }

        public override PointBase MiddlePosition
        {
            get
            {
                return PointHelper.GetPointForConnector(this, true);               
            }
        }

        private List<CinchMenuItem> menuOptions;
        public IEnumerable<CinchMenuItem> MenuOptions
        {
            get
            {
                return menuOptions;
            }
        }

        public DesignerItemViewModelBase DataItem
        {
            get
            {
                return Parent as DesignerItemViewModelBase;
            }
        }

        private bool _showConnectors = false;
        public bool ShowConnectors
        {
            get
            {
                return _showConnectors;
            }
            set
            {
                SetProperty(ref _showConnectors, value);
            }
        }

        private double _xRatio;
        public double XRatio
        {
            get
            {
                return _xRatio;
            }
            set
            {
                SetProperty(ref _xRatio, value);
            }
        }

        private double _yRatio;
        public double YRatio
        {
            get
            {
                return _yRatio;
            }
            set
            {
                SetProperty(ref _yRatio, value);
            }
        }

        public PointBase Ratio
        {
            get
            {
                return new PointBase(XRatio, YRatio);
            }
            set
            {
                XRatio = value.X;
                YRatio = value.Y;
            }
        }

        public bool IsInnerPoint
        {
            get; set;
        }

        public bool IsPortless
        {
            get; set;
        }

        private Style _style;
        public Style Style
        {
            get
            {
                return _style;
            }
            set
            {
                SetProperty(ref _style, value);
            }
        }
        #endregion

        #region 方法
        public ICommand DeleteCommand
        {
            get; private set;
        }
        public ICommand MenuItemCommand
        {
            get; private set;
        }
        #endregion

        public void ExecuteMenuItemCommand(object arg)
        {
            Orientation = (ConnectorOrientation)arg;
            DataItem.Left += 0.1;
            DataItem.Left -= 0.1;
        }

        public void ExecuteDeleteCommand(object arg)
        {
            DataItem.RemoveConnector(this);

        }

        private void BuildMenuOptions()
        {
            menuOptions.Clear();
            var orientation = new CinchMenuItem("方向");
            var none = new CinchMenuItem("无");
            none.Command = MenuItemCommand;
            none.CommandParameter = ConnectorOrientation.None;
            var top = new CinchMenuItem("上");
            top.Command = MenuItemCommand;
            top.CommandParameter = ConnectorOrientation.Top;
            var bottom = new CinchMenuItem("下");
            bottom.Command = MenuItemCommand;
            bottom.CommandParameter = ConnectorOrientation.Bottom;
            var left = new CinchMenuItem("左");
            left.Command = MenuItemCommand;
            left.CommandParameter = ConnectorOrientation.Left;
            var right = new CinchMenuItem("右");
            right.Command = MenuItemCommand;
            right.CommandParameter = ConnectorOrientation.Right;
            orientation.Children.Add(none);
            orientation.Children.Add(top);
            orientation.Children.Add(bottom);
            orientation.Children.Add(left);
            orientation.Children.Add(right);

            var delete = new CinchMenuItem("删除");
            delete.Command = DeleteCommand;

            menuOptions.Add(orientation);
            menuOptions.Add(delete);
        }

        public double GetXRatioFromConnector()
        {
            if (IsInnerPoint)
            {
                return XRatio;
            }
            else if (IsPortless)
            {
                return 0.5;
            }
            else
            {
                switch (Orientation)
                {
                    case ConnectorOrientation.Left:
                        return 0;
                    case ConnectorOrientation.TopLeft:
                        return 0;
                    case ConnectorOrientation.Top:
                        return 0.5;
                    case ConnectorOrientation.TopRight:
                        return 1;
                    case ConnectorOrientation.Right:
                        return 1;
                    case ConnectorOrientation.BottomRight:
                        return 1;
                    case ConnectorOrientation.Bottom:
                        return 0.5;
                    case ConnectorOrientation.BottomLeft:
                        return 0;
                    default: return XRatio;
                }
            }
        }

        public double GetYRatioFromConnector()
        {
            if (IsInnerPoint)
            {
                return YRatio;
            }
            else if (IsPortless)
            {
                return 0.5;
            }
            else
            {
                switch (Orientation)
                {
                    case ConnectorOrientation.Left:
                        return 0.5;
                    case ConnectorOrientation.TopLeft:
                        return 0;
                    case ConnectorOrientation.Top:
                        return 0;
                    case ConnectorOrientation.TopRight:
                        return 0;
                    case ConnectorOrientation.Right:
                        return 0.5;
                    case ConnectorOrientation.BottomRight:
                        return 1;
                    case ConnectorOrientation.Bottom:
                        return 1;
                    case ConnectorOrientation.BottomLeft:
                        return 1;
                    default: return YRatio;
                }
            }
        }

        public override bool CanAttachTo(ConnectorInfoBase port)
        {
            if (port is FullyCreatedConnectorInfo fullyCreatedConnectorInfo)
            {
               return port != this && !port.IsReadOnly && DataItem != fullyCreatedConnectorInfo.DataItem;
            }
            else
            {
                return base.CanAttachTo(port);
            }
        }

        public override string ToString()
        {
            return $"({GetXRatioFromConnector()},{GetYRatioFromConnector()})";
        }
    }


}
